#ifndef DICT_H
#define DICT_H

#include "bool.h"
#include "key.h"
#include "data.h"
#include "abb.h"
#include "pila.h"

typedef struct sdict *dict;

dict 
dict_empty(void);

/*
  DESC: Constructor del tipo. Crea un diccionario vacio.
  PRE: { d = NULL }
  d = dict_empty(f);
  POS: {  Hay memoria  ==> d --> empty
  ! Hay memoria  ==> d == NULL }
*/

dict
dict_fromFile(char * f);
/*
  DESC: Constructor del tipo. Crea un diccionario a partir de un archivo.
  Toma el nombre del archivo.
  PRE: { d = NULL }
  d = dict_fromFile(f);
  POS: {  Hay memoria /\ ! Error de Archivo ==> d --> fromFile(f) 
  ! Hay memoria \/   Error de Archivo ==> d == NULL }
*/

dict 
dict_destroy(dict d);
/*
  DESC: Destructor del tipo. d cambia.
  PRE: { d --> D }
  d = dict_destroy(d);
  POS: { Se destruye D /\ d == NULL }
*/

bool
dict_toFile(char *f , const dict d);
/*
  DESC: Guarda el diccionario en el archivo f.
  PRE: { d --> D }
  b = dict_toFile(f, d);
  POS: { ! Error de Archivo ==>  b /\ D guardado en archivo f 
  Error de Archivo ==> !b }
*/

dict
dict_add(dict d, const key k, const data e);
/*
  DESC: Agrega en el diccionario el dato d con la clave k.
  Si la clave ya existe no hace nada.
  Si agrega no utiliza k ni e (copia).
  PRE: { d --> D /\ k --> K /\ e --> E /\ !exist(D,K)}
  d = dict_add(d, k, e);
  POS: { d --> add(D,K,E) }
*/

bool
dict_exist(const dict d, const key k);
/*
  DESC: Busca el dato con clave k si existe. Si no existe devuelve False.
  PRE: { d --> D /\ k --> K }
  b = dict_exist(d, k);
  POS: { (D =  add(D',K,E) /\ b ) \/ 
  (D != add(D',K,E) /\ !b ) }
*/

data
dict_search(const dict d, const key k);
/*
  DESC: Busca y trae el dato con clave k si existe. Si no devuelve NULL.
  Crea copia del dato.
  PRE: { d --> D /\ k --> K /\ e = NULL }
  e = dict_search(d, k);
  POS: { (D =  add(D',K,E) /\ e --> E ) \/ 
  (D != add(D',K,E) /\ e = NULL ) }
*/

dict
dict_del(dict d, const key k);
/*
  DESC: Borra el dato con clave k. Si no esta devuelve null. 
  Destruye contenidos.
  PRE: { d --> D /\ k --> K /\ e = NULL }
  d = dict_del(d, k);
  POS: { ( D  = add(D',K,E) /\ d --> D') \/
  ( D != add(D',K,E) /\ d --> D }
*/

int
dict_length(dict d);
/*
  DESC: Devuelve la cantidad de estradas en el diccionario. 
  PRE: { d --> D }
  l = dict_length(d);
  POS: { l = length(D) }
*/


int
lsearch(dict d, key k);

/* Swap */
/*void
dic_swap(dict d, int a, int b);*/


#endif /* DICT_H */
